package com.hc.kotlin_coroutine

import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.zip
import kotlinx.coroutines.runBlocking

fun main() {
    runBlocking {
        println("------zip------")
        val flow1 = flowOf(1,2,3)
        val flow2 = flowOf("a","b","c","d","e")
        flow1.zip(flow2){ i,j->
            j + i
        }.collect{
            println(it)
        }
        //模拟并发执行,但又需都执行完
        getInfo1().zip(getInfo2()){ i1,i2->
            "总信息:$i1$i2"
        }.collect{
            println(it)
        }
        println("------buffer------")
        flow {
            emit(1)
            delay(1000)
            emit(2)
            delay(1000)
            emit(3)
        }.onEach {
            println("$it is ready")
        }
        .buffer() //对比此行注释后打印效果
        .collect{
            delay(1000) //不添加buffer后,会导致flow挂起
            println("$it is handled")
        }
        println("------conflate------")
        flow {
            var i = 0
            while (true){
                emit(i)
                delay(1000)
                i++
            }
        }
        .conflate()
        .collect{
            println("start $it")
            delay(2000) //conflate 等待当前数据处理完再处理最新数据
            println("end $it")
        }
//        .collectLatest{ //只处理最新数据,前一数据处理会取消
//            println("start $it")
//            delay(2000)
//            println("end $it")
//        }
    }
}

fun getInfo1():Flow<String>{
    return flow {
        delay(1000)
        emit("信息1")
    }
}
fun getInfo2():Flow<String>{
    return flow {
        delay(2000)
        emit("信息2")
    }
}